﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xpus.Website.Utilities;

namespace Xpus.Website.Core.UrlTools
{
	/// <summary>
	/// 用于处理URL。
	/// </summary>
	public class UrlHelper
	{
		/// <summary>
		/// Xpus页面的后缀。
		/// </summary>
		public const string XpusPagePostfix = ".x";

		/// <summary>
		/// 默认的域名。
		/// </summary>
		public const string XpusDomain = "www";

		/// <summary>
		/// 默认的主机名。
		/// </summary>
		public const string XpusHost = "xpus.net";

		/// <summary>
		/// 当在本机访问时的主机名。
		/// </summary>
		public const string XpusLocalHost = "localhost";

		/// <summary>
		/// HTTP前缀。
		/// </summary>
		public const string HttpPrefix = "http://";

		const int DfaAcceptRoot = 11;
		const int DfaAcceptPath = 12;
		const int DfaAcceptSubpath = 13;
		const int DfaAcceptYearArchive = 14;
		const int DfaAcceptMonthArchive = 15;
		const int DfaAcceptDayArchive = 16;
		const int DfaAcceptContent = 17;
		const int DfaError = -1;
		private static readonly int[,] parserDfaStatus =
		{
   {1, DfaError, DfaError, DfaError, DfaError, DfaError},
   {DfaError, 2, DfaError, DfaError, DfaError, DfaError},
   {3, 3, 3, DfaError, DfaError, DfaError},
   {DfaError, DfaError, DfaError, 4, DfaError, DfaError},
   {DfaError, DfaError, DfaError, DfaError, 5, DfaError},
   {DfaError, DfaError, DfaError, DfaError, DfaError, DfaAcceptContent},
   {DfaAcceptRoot, DfaAcceptPath, DfaAcceptSubpath, DfaAcceptYearArchive, DfaAcceptMonthArchive, DfaAcceptDayArchive}
		};

		/// <summary>
		/// 将一个url拆解为一个<see cref="UrlStructure"/>对象。
		/// </summary>
		/// <param name="url">待拆解的url。</param>
		/// <returns>拆解后的url。</returns>
		public static UrlStructure ParseUrl(string url)
		{
			if(url == null)
				throw new ArgumentNullException("url");

			UrlStructure result = new UrlStructure();

			// 去除“http://”前缀
			if(url.StartsWith(HttpPrefix))
				url = url.Remove(0, HttpPrefix.Length);

			// 将其余部分以“/”为界切分
			string[] parts = url.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);

			int cur = 0;  // 表示当前分析到哪一部分

			// 分析二级域名和主机名
			int hostpos = -1;
			string part = parts[cur];

			if((hostpos = part.LastIndexOf(XpusHost)) != -1)
				result.Host = XpusHost;
			else if((hostpos = part.LastIndexOf(XpusLocalHost)) != -1)
				result.Host = XpusLocalHost;

			if(hostpos == -1 || hostpos != part.Length - result.Host.Length)  // 必须找到host，并且host是整个域名的最后一部分
				throw new UrlFormatException(url, result.Host);

			result.Domain = part.Substring(0, part.Length - result.Host.Length - 1);
			if(!RegexUtility.GetRegex("AreaAccessKey").IsMatch(result.Domain))
				throw new UrlFormatException(url, result.Domain);

			return result;
		}

		/// <summary>
		/// 从输入的part得到其编号。
		/// </summary>
		/// <param name="part">URL中的一个路径部分。</param>
		/// <returns>该部分对应的编号。</returns>
		private static int GetPartNo(string part)
		{
			return 0;
		}
	}

	/// <summary>
	/// 表示解析后的URL结构。
	/// </summary>
	public class UrlStructure
	{
		#region URL结构部分
		// 这些属性表示URL的构成部分。
		// xpus所处理的页面，其URL可能是（经过正规化）
		// - http://[domain].[host]/[path]/[subpath]/[year]/[month]/[day]/[filetitle].x

		/// <summary>
		/// 获取或设置URL中的[domain]部分。
		/// </summary>
		public string Domain
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[host]部分。
		/// </summary>
		public string Host
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[path]部分。
		/// </summary>
		public string Path
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[subpath]部分。
		/// </summary>
		public string Subpath
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[year]部分。
		/// </summary>
		public int Year
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[month]部分。
		/// </summary>
		public int Month
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[day]部分。
		/// </summary>
		public int Day
		{
			get;
			set;
		}

		/// <summary>
		/// 获取或设置URL中的[filetitle]部分。
		/// </summary>
		public string FileTitle
		{
			get;
			set;
		}
		#endregion

		/// <summary>
		/// 已重写。返回<see cref="UrlStructure"/>对象所代表的完整URL。
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			StringBuilder sbUrl = new StringBuilder();

			sbUrl.Append("http://");

			if(!string.IsNullOrEmpty(Domain))
			{
				sbUrl.Append(Domain);
				sbUrl.Append(".");
			}

			sbUrl.Append(Host);
			sbUrl.Append("/");

			if(!string.IsNullOrEmpty(Path))
			{
				sbUrl.Append(Path);
				sbUrl.Append("/");

				if(!string.IsNullOrEmpty(Subpath))  // 如果path是空，则忽略subpath
				{
					sbUrl.Append(Subpath);
					sbUrl.Append("/");
				}
			}

			if(Year != 0)
			{
				sbUrl.Append(Year.ToString("0000"));
				sbUrl.Append("/");

				if(Month != 0)
				{
					sbUrl.Append(Month.ToString("00"));
					sbUrl.Append("/");

					if(Day != 0)
					{
						sbUrl.Append(Day.ToString("00"));
						sbUrl.Append("/");

						if(!string.IsNullOrEmpty(FileTitle))
						{
							sbUrl.Append(FileTitle);
							sbUrl.Append(UrlHelper.XpusPagePostfix);
						}
					}
				}
			}

			return sbUrl.ToString();
		}
	}
}
